package com.emerquim.bean.model;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;

import com.emerquim.bean.support.ControlDespliegue;
import com.emerquim.persistence.dao.PAgente;
import com.emerquim.persistence.dao.PAgenteDAO;
import com.icesoft.faces.context.effects.JavascriptContext;

/**
 * Clase para manejar los agentes
 * @author Felipe Criales
 */
public class ManejadorAgentes {

	/**
	 * Funcionalidad de log
	 */
	private static final Logger log = Logger.getLogger(ManejadorAgentes.class);

	// ---------------------------------------
	// Atributos
	// ---------------------------------------

	/**
	 * El resultado de la busqueda de agentes
	 */
	private List<Agente> resultadosAgentes;

	/**
	 * Atributo para el nombre del producot a buscar
	 */
	private String nombreProductoBuscar;

	/**
	 * Constructor de la clase
	 */
	public ManejadorAgentes(){
		this.inicializarDatos();
	}

	/**
	 * Metodo para limpiar los datos del manejador de agentes
	 */
	public void inicializarDatos(){
		this.resultadosAgentes = new ArrayList<Agente>();
		this.nombreProductoBuscar = "";
	}

	/**
	 * Metodo para buscar los agentes
	 * @param event
	 * @author Felipe Criales
	 */
	public void buscarAgentes(ActionEvent event){	
		resultadosAgentes = new ArrayList<Agente>();
		PAgenteDAO agenteDao = new  PAgenteDAO();
		try  {
			List listaAgentes = agenteDao.findAll();
			Iterator<PAgente> it = listaAgentes.iterator();
			while(it.hasNext()){
				PAgente pAgente = (PAgente)it.next();
				if(pAgente.getAgeDesc().toLowerCase().contains(this.nombreProductoBuscar.toLowerCase())){
					Agente miAgente = this.crearAgente(pAgente);	
					resultadosAgentes.add(miAgente);
				}	
			}
		}catch  (HibernateException e) {
			log.error("Error al buscar los agentes en la base de datos", e);			
		}finally  {
			agenteDao.getSession().close();			
		}	
	}

	/**
	 * Metodo para crear un agente a partir de un PAgente
	 * @param pAgente El objeto pagente
	 * @author Felipe Criales
	 */
	private Agente crearAgente(PAgente pAgente){
		// TODO Recuperar el idClaseOnu y la clase onu y el gre
		Agente agenteRetornar = new Agente();
		agenteRetornar.inicializarDatos(); // Para blanquear todos los datos
		try{
			agenteRetornar.setIdAgente(longToInt(pAgente.getAgeId()));
			agenteRetornar.setNombreProducto(pAgente.getAgeDesc());
			agenteRetornar.setHojaSeguridad(pAgente.getAgeHojaseg());
			if(pAgente.getPIngActivo() != null){
				agenteRetornar.setIdIngredienteActivo(longToInt(pAgente.getPIngActivo().getIacId()));
				agenteRetornar.setIngredienteActivo(pAgente.getPIngActivo().getIacDesc());
			}
			if(pAgente.getPGrupoQuimico() != null){
				agenteRetornar.setIdGrupoQuimico(longToInt(pAgente.getPGrupoQuimico().getGrqId()));
				agenteRetornar.setGrupoQuimico(pAgente.getPGrupoQuimico().getGrqDesc());
			}
			if(pAgente.getPUso() != null){
				agenteRetornar.setIdUso(longToInt(pAgente.getPUso().getUsoId()));
				agenteRetornar.setUso(pAgente.getPUso().getUsoDesc());
			}
			if(pAgente.getPEstadoFisico() != null){
				agenteRetornar.setIdEstadoFisico(longToInt(pAgente.getPEstadoFisico().getEsfId()));
				agenteRetornar.setEstadoFisico(pAgente.getPEstadoFisico().getEsfDesc());
			}
			if(pAgente.getPCatToxicologica() != null){
				agenteRetornar.setIdCategoriaToxicologica(longToInt(pAgente.getPCatToxicologica().getCtxId()));
				agenteRetornar.setCategoriaToxicologica(pAgente.getPCatToxicologica().getCtxDesc());
			}
			if(pAgente.getPEmpresasProductoras() != null){
				agenteRetornar.setIdEmpresa(longToInt(pAgente.getPEmpresasProductoras().getEprId()));
				agenteRetornar.setNombreEmpresa(pAgente.getPEmpresasProductoras().getEprNom());
			}
			agenteRetornar.setConfirmado(false);
			agenteRetornar.setSeleccionado(false);		
			agenteRetornar.setCantidad(0);
		}catch  (Exception e) {
			log.error("Error al crear un agente", e);			
		}
		return agenteRetornar;
	}

	/**
	 * Metodo para convertir un valor de long a int
	 * @param valor
	 */
	private int longToInt(long valor){
		return Integer.parseInt(String.valueOf(valor));
	}

	/**
	 * Metodo para buscar los agentes
	 * @param event
	 */
	public void adicionarAgentePaciente(ActionEvent event){
		// 1. Buscar el agente seleccionado y agregar al paciente
		FacesContext context = FacesContext.getCurrentInstance();
		Iterator it = resultadosAgentes.iterator();
		boolean agregoAgente = false;
		while(it.hasNext()){
			Agente agente = (Agente)it.next();
			if(agente.isSeleccionado()){
				agregoAgente = true;	
				Paciente paciente = (Paciente) context.getApplication().evaluateExpressionGet(context, "#{paciente}", Paciente.class);
				if(paciente != null){
					agente.setSeleccionado(false);
					paciente.adicionarAgente(agente);					
				}
			}				
		}
		// 3. Regresar a la vista de paciente
		if(agregoAgente){
			ControlDespliegue controlDespliegue = (ControlDespliegue) context.getApplication().evaluateExpressionGet(context, "#{controlDespliegue}", ControlDespliegue.class);
			if(controlDespliegue != null)
				controlDespliegue.setIndexTabPrincipal(ControlDespliegue.INDEX_TAB_PACIENTE);
			// 3.1 Limpiar los datos del paciente
			this.inicializarDatos();
		}    	
		else{
			JavascriptContext.addJavascriptCall(FacesContext
					.getCurrentInstance(), "alert('Debe seleccionar un agente de la tabla para adionarlo');");	
		}	
	}

	/**
	 * @return the resultadosAgentes
	 */
	public List<Agente> getResultadosAgentes() {
		return resultadosAgentes;
	}

	/**
	 * @param resultadosAgentes the resultadosAgentes to set
	 */
	public void setResultadosAgentes(List<Agente> resultadosAgentes) {
		this.resultadosAgentes = resultadosAgentes;
	}

	/**
	 * @return the nombreProductoBuscar
	 */
	public String getNombreProductoBuscar() {
		return nombreProductoBuscar;
	}

	/**
	 * @param nombreProductoBuscar the nombreProductoBuscar to set
	 */
	public void setNombreProductoBuscar(String nombreProductoBuscar) {
		this.nombreProductoBuscar = nombreProductoBuscar;
	}
}
